package com.boil.qz.safekavass.service;

import com.boil.pojo.ResultVo;
import com.boil.qz.safekavass.dao.MybatisDao;
import com.boil.qz.safekavass.model.LoginUser;
import com.boil.qz.safekavass.model.Question;
import com.boil.qz.safekavass.repository.LoginUserRepository;
import com.boil.qz.safekavass.shiro.util.ShiroUtils;
import com.boil.qz.safekavass.web.request.param.UpdateLoginUserParam;
import com.boil.qz.safekavass.websocket.WebSocketTextServer;
import com.boil.util.Constants;
import com.boil.util.Page;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created by ChenYong on 2017-04-11.
 * 用户 Service。
 */
@Service
public class LoginUserService extends JpaRepositoryService<LoginUser, Long> {
    /**
     * 注入 Mybatis Dao
     */
    @Autowired
    private MybatisDao mybatisDao;
    /**
     * 注入登录用户实体仓库
     */
    @Autowired
    private LoginUserRepository loginUserRepository;
    /**
     * 注入 WebSocket 文本服务器
     */
    @Autowired
    private WebSocketTextServer webSocketTextServer;


    /**
     * 根据登录 ID 查询用户。
     *
     * @param loginid 登录 ID
     * @return 用户实例
     */
    public LoginUser findByLoginid(String loginid) {
        if (StringUtils.isEmpty(loginid)) {
            return null;
        }

        return loginUserRepository.findByLoginid(loginid);
    }

    /**
     * 根据登录 ID 查询管理员。
     *
     * @param loginid 登录 ID
     * @return 用户实例
     */
    public LoginUser findAdminByLoingid(String loginid) {
        if (StringUtils.isEmpty(loginid)) {
            return null;
        }

        return loginUserRepository.findAdminByLoingid(loginid);
    }

    /**
     * 分页查询用户。
     *
     * @param page 分页实例
     */
    public void findInPage(Page<Question> page) {
        mybatisDao.selectInPage("loginUserVoNs.findInPage", page);
    }

    /**
     * 更新用户。
     *
     * @param id    用户 ID
     * @param param 更新用户的请求参数
     */
    public LoginUser updateById(long id, UpdateLoginUserParam param) {
        if ((id == Constants.VALUE_L_0) || param == null) {
            return null;
        }

        LoginUser loginUser1 = findOne(id);
        BeanUtils.copyProperties(param, loginUser1);

        LoginUser loginUser2 = new LoginUser();
        BeanUtils.copyProperties(loginUser1, loginUser2);
        // 居于安全考虑，将密码设置为空
        loginUser2.setPwd(null);

        return loginUser2;
    }

    /**
     * 更新用户密码。
     *
     * @param id        用户 ID
     * @param newPasswd 新密码（未加密的密码）
     * @return 更新的记录数
     */
    public LoginUser updatePasswdById(long id, String newPasswd) {
        if ((id == Constants.VALUE_L_0) || StringUtils.isBlank(newPasswd)) {
            return null;
        }

        LoginUser loginUser1 = findOne(id);
        loginUser1.setPwd(ShiroUtils.passwd2Md5(newPasswd));

        LoginUser loginUser2 = new LoginUser();
        BeanUtils.copyProperties(loginUser1, loginUser2);
        // 居于安全考虑，将密码设置为空
        loginUser2.setPwd(null);

        return loginUser2;
    }

    /**
     * 登录验证。
     *
     * @param resultVo          结果 Vo
     * @param shiroLoginFailure Shiro 登录失败信息
     * @param account           账号
     */
    public void doLogin(ResultVo resultVo, String shiroLoginFailure, String account) {
        if ((resultVo == null) || //
                StringUtils.isEmpty(account)) {
            log.error("账号：{}--->登录失败，系统繁忙", account);

            resultVo.setResultCode(Constants.SYS_ERROR);
            resultVo.setResultMsg(Constants.SYS_ERROR_MSG);

            // 登录验证
        } else {
            resultVo.setResult(account);

            // 登录账号不存在
            if (UnknownAccountException.class.getName().equals(shiroLoginFailure)) {
                resultVo.setResultCode(Constants.LOGIN_ACCOUNT_NOT_EXIST);
                resultVo.setResultMsg(Constants.LOGIN_ACCOUNT_NOT_EXIST_MSG);

                log.error("登录账号：{}--->Shiro 登录认证失败，原因是：账号不存在（{}）。", account, shiroLoginFailure);

                // 登录密码错误
            } else if (IncorrectCredentialsException.class.getName().equals(shiroLoginFailure)) {
                resultVo.setResultCode(Constants.LOGIN_PASSWD_ERROR);
                resultVo.setResultMsg(Constants.LOGIN_PASSWD_ERROR_MSG);

                log.error("登录账号：{}--->Shiro 登录认证失败，原因是：密码错误（{}）。", account, shiroLoginFailure);

                // 系统出现异常
            } else {
                resultVo.setResultCode(Constants.SYS_ERROR);
                resultVo.setResultMsg(Constants.SYS_ERROR_MSG);

                log.error("登录账号：{}--->Shiro 登录认证失败，原因是：系统出现异常（{}）。", account, shiroLoginFailure);
            }
        }
    }
}